use std::{env, fs};
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::{Path, PathBuf};

fn main() {
    File::create("directory/example.txt").unwrap();

    // 只能创建单个目录
    match fs::create_dir("directory") {
        Ok(()) => println!("项目根目录下创建目录成功！"),
        Err(e) => eprintln!("项目根目录下创建目录失败: {}", e),
    }

    // 创建整个路径中的所有目录，即使其中一些目录不存在
    let dir_path = "path/to/directory";
    match fs::create_dir_all(dir_path) {
        Ok(()) => println!("递归创建目录成功！"),
        Err(e) => eprintln!("递归创建目录失败: {}", e),
    }

    // 创建文件
    let file_path = "path/to/directory/myfile.txt";
    match File::create(file_path) {
        Ok(mut file) => {
            println!("在指定路径创建文件成功！");
            file.write_all(b"Hello, world!").expect("Failed to write to file");
        },
        Err(e) => eprintln!("在指定路径创建文件失败: {}", e),
    }

    // 使用std::env模块中的current_dir函数来获取当前工作目录。这个函数返回一个Result类型，Ok包含当前工作目录的路径，Err包含一个错误信息。
    match env::current_dir() {
        Ok(current_dir) => println!("当前目录是: {:?}", current_dir),
        Err(e) => eprintln!("无法获取当前目录: {}", e),
    }

    // 获取当前文件的绝对路径
    match env::current_exe() {
        Ok(exe_path) => println!("可执行文件路径为: {:?}", exe_path),
        Err(e) => eprintln!("无法获取可执行文件路径: {}", e),
    }

    // 在已有的目录下查找文件
    // 假设你有一个名为 example.txt 的文件位于程序的同一目录下，你可以这样获取它的路径：
    // 在这个示例中，我们首先获取当前可执行文件的路径，然后找到其父目录，并在该目录中查找 example.txt 文件。请注意，这里假设 example.txt 与可执行文件位于同一目录下。
    // 如果你的文件位于不同的目录结构中，你需要相应地调整路径。
    let file_path = Path::new(&env::current_dir().unwrap()).join("log.txt");
    println!("文件路径为: {:?}", file_path);

    // 读取文件内容
    match fs::read_to_string(&file_path) {
        Ok(contents) => {
            println!("文件内容为:");
            println!("{}", contents)
        },
        Err(e) => eprintln!("无法读取文件: {}", e),
    }

    // 有时候你可能需要更细粒度的控制，例如逐行读取文件或使用缓冲流来提高性能。这时你可以使用 std::fs::File 和 std::io::BufReader。
    match File::open(&file_path) {
        Ok(file) => {
            println!("逐行读取文件内容!");
            let reader = BufReader::new(file);
            for line in reader.lines() {
                match line {
                    Ok(line) => println!("{}", line),
                    Err(e) => eprintln!("无法读取行: {}", e),
                }
            }
        },
        Err(e) => eprintln!("无法打开文件: {}", e),
    }

    // 使用宏读取静态文件内容，读取同层级目录下的 greeting.txt 文件内容
    let greeting = include_str!("greeting.txt");
    println!("Greeting: {}", greeting);


    // 获取当前文件的路径
    let file_path = file!();    // 当前文件路径: src/main.rs
    println!("当前文件路径: {}", file_path);
    // 将文件路径转换为 PathBuf 对象
    let path_buf = PathBuf::from(file_path);
    // 获取文件所在的目录
    if let Some(parent_dir) = path_buf.parent() {
        println!("当前文件所在目录: {}", parent_dir.display());    // 当前文件所在目录: src
    } else {
        println!("无法确定当前文件所在目录");
    }

    // 创建一个文件路径
    let path = Path::new("./rust-time/").join("src/main.rs");
    println!("{:?}", path.display());
    let path = Path::new("./rust-time/").join("src").join("main.rs");
    println!("{:?}", path.display());

    // 假设您有一个文件路径
    let base_path = PathBuf::from("/path/to/directory");
    // 假设您有一个变量表示文件名
    let file_name = "example.txt";
    // 将文件名拼接到基础路径中
    let full_path = base_path.join(file_name);
    // 输出完整的文件路径
    println!("Full path: {}", full_path.display());

    // 变量
    let subdirectory = "subdir";
    let file_name = "example.txt";
    // 构建完整的文件路径
    let full_path = base_path.join(subdirectory).join(file_name);
    // 输出完整的文件路径
    println!("Full path: {}", full_path.display());


    // 遍历目录下的所有直接文件和目录
    let paths = fs::read_dir("./rust-time/").unwrap(); // 可迭代对象ReadDir
    let file_arr = paths
        .map(|f| f.unwrap().path().file_name().unwrap().to_str().unwrap().to_owned())
        .collect::<Vec<String>>();
    println!("{:?}", file_arr);


    // 获取当前文件的路径
    let file_path = file!();    // 当前文件路径: src/main.rs
    println!("当前文件路径: {}", file_path);
    // 将文件路径转换为 PathBuf 对象
    let path_buf = PathBuf::from(file_path);
    // 获取文件所在的目录
    if let Some(parent_dir) = path_buf.parent() {
        println!("当前文件所在目录: {}", parent_dir.display());    // 当前文件所在目录: rust-jwt/src
        // 拼接证书存放目录
        let cert_dir = parent_dir.join("cert");
        println!("拼接后的证书存放目录: {}", cert_dir.display());
        // 只能创建单个目录
        match fs::create_dir(&cert_dir) {
            Ok(()) => {
                println!("项目根目录下创建cert证书存放目录成功！");

                // 写入私钥和证书到文件
                // 创建文件不能使用以 / 开头的绝对路径，只能使用相对路径
                let server_key_path = &cert_dir.join("server.key");
                let mut file = File::create(server_key_path).unwrap();
            },
            Err(e) => eprintln!("项目根目录下创建目录失败: {}", e),
        }
    } else {
        println!("无法确定当前文件所在目录");
    }
}